/*
@Time : 2022/5/28 18:01
@Author : gaozhichang
@File : cron1.go
@des: GoLand
*/
/*
	一个简单的定时任务轮询脚本
	功能：
	1. 定义标task interface 可以支持多个任务运行。
	2. 支持 context.context，主程序退出，会等待子协程退出。
	3. 支持手动退出信号
*/
package main

import (
	"context"
	"fmt"
	"log"
	"os"
	"os/signal"
	"sync"
	"time"
)

var NotifyWg *sync.WaitGroup
type TaskInterface func(ctx context.Context,  wg *sync.WaitGroup)
var Tasks []TaskInterface
var TaskCancels  []context.CancelFunc

func init()  {
	//--------添加任务---------
	//设置使用核数
	//runtime.GOMAXPROCS(1)
	NotifyWg = &sync.WaitGroup{}
	//添加任务
	addTask(SendTask)
	//addTask(PushStatusTask)
}

func main()  {



	//---------启动协程---------
	for _,task:=range Tasks{
		ctx, cancel1 := context.WithCancel(context.Background())
		go task(ctx, NotifyWg)
		TaskCancels = append(TaskCancels, cancel1)
	}

	//用于主进程退出
	exit := make(chan os.Signal)
	signal.Notify(exit, os.Interrupt, os.Kill)
	defer close(exit)

	//主进程死循环
	after2SecondMain 	:= time.Tick(2 * time.Minute)
	for {
		select {
		case s:=<-exit:
			log.Println(fmt.Sprintf("捕获退出信号 %v，通知协程退出",s))
			cancelAll()
			//等待协程退出
			NotifyWg.Wait()
			log.Println(fmt.Sprintf("协程都停止了，可以退出了"))
			return
		case <-after2SecondMain:
			log.Println(fmt.Sprintf("【主进程心跳】，每次休息2分钟"))
		}
	}
}

//添加任务
func addTask(task TaskInterface)  {
	Tasks = append(Tasks, task)
	NotifyWg.Add(1)
}

//context cancel
func cancelAll()  {
	for _,cancel:=range TaskCancels{
		cancel()
	}
}

//-------task----
func PushStatusTask(ctx context.Context, wg *sync.WaitGroup) {
	log.Println("in PushStatusTask")
	after1Second 	:= time.Tick(10 * time.Second)
	for {
		select {
		case <-ctx.Done():
			log.Println("in PushStatusTask get ctx.done")
			wg.Done()
			return
		case <-after1Second:
			log.Println("PushStatusTask do something")
		}
	}
}
func SendTask(ctx context.Context, wg *sync.WaitGroup) {
	log.Println("in SendTask")
	after1Second 	:= time.Tick(2 * time.Second)
	for {
		select {
		case <-ctx.Done():
			log.Println("in SendTask get ctx.done")
			wg.Done()
			return
		case <-after1Second:
			log.Println("SendTask do something")
		}
	}

}